R ile Büyük Veri Üzerinde Çalışma, Görselleştirme ve Modelleme

1. Önsöz

MARMARA ÜNİVERSİTESİ

FEN-EDEBİYAT FAKÜLTESİ İSTATİSTİK BÖLÜMÜ

ARAŞTIRMA PROJESİ

Danışman: Müjgan TEZ

1.1 Amaç

BÜYÜK VERİ ile çalışmak, belirli veri analizi araçları, paketleri ve makine öğrenimi gibi gelişmiş teknikler gerektirir. Bu çalışma, büyük verileri keşfetmek, görselleştirmek, ve modellemek için R içerisinde bulunan araçların ve makine öğrenimi yöntemlerinin kullanımına ilişkin uygulamalı bir eğitim olacaktır.

Çalışmamız, lisans eğitimi boyunca öğrendiklerimiz ve bu konu üzerinde geliştirme amacıyla yaptığımız çalışmalarımızın bir çıktısıdır.

1.2 Proje Üyeleri

  • Tarık ÇELİK

  • Enes Malik DİCLE

  • Gizem ATEŞ

  • Yaren DEMİRBAŞ


2. Giriş

2.1 Büyük Veri Nedir?

Büyük veri; verinin analiz edilip sınıflandırılmış, anlamlı ve işlenebilir hale dönüştürülmüş halidir. Yükselen teknolojiler ve tüketicilerin artan veri kullanım oranı paralelinde daha fazla çeşitlilik içeren veri kümesidir.

Büyük verinin 3 karakteristik özelliği olan İngilizce’deki variety, velocity ve volume kelimelerinden türeyen 3V kavramıdır. Büyük veriyi daha iyi anlamamıza yardımcı olurlar.

  • Çeşitlilik (Variety): Büyük veri çeşitliliği yapılan sorgularda daha eksiksiz cevap almaya yarar. Çünkü veriler metin belgelerinden e-postalara, sayısal verilerden, videolara, seslere, finansal işlemlere kadar her türlü farklı formatlardan derlenebilir.

  • Hız (Velocity): Gerçek zamanlı veri oluşturulma hızını ifade etmektedir. Daha geniş bir bakışla, değişim oranını, gelen veri setlerinin değişen hızlarda bağlanmasını ve etkinlik patlamalarını içerir.

  • Hacim (Volume): Adından da anlaşıldığı gibi büyük verinin günlük bazda oluşturulan devasa bilgi setleri olduğunu biliyoruz. Bu kaynaklar sosyal medya, iş süreçleri, makineler, ağlar, veya insan etkileşimleri olabilir.

Şekil 2.1: Büyük Veride 3V

2.2 Büyük Veri Neden Önemlidir?

Big Data ne kadar bilgi sahibi olunduğundan ziyade onunla ne yapılacağı üzerine yoğunlaşıyor. Herhangi bir kaynaktan veri alıp onları para ve zaman tasarrufu (maliyet azaltma), yeni proje, ürün, hizmet gelişimi ve optimize edilmiş önerileri aynı zamanda da akıllı karar verilmesini sağlayan cevaplar bulmak için analiz edebilirsiniz. Büyük veri güçlü analizlerle birleştiğinde iş ile alakalı şunlar gerçekleştirilebilir:

  • Gerçek zamanlı hata ve sorunların temel nedenlerini belirleme.
  • Müşterilerin satın alma alışkanlıklarına dayanarak satış amaçlı kuponlar üretme.
  • Yeni portfolyoların risklerini tekrar hesaplama.
  • İşleyişi etkilemeden önce yanlış davranışları tespit etme.

Büyük verilerin önemi, sahip olduğunuz verinin ne olduğu, ne yaptığınızla ilgili değildir.

2.3 Büyük Verinin Çalışması için Üç Yöntem

Strateji 1: Örnek ve Model

  • Örneklemek ve modellemek için, verilerimizi tümüyle kolayca indirilebilecek bir boyuta küçültürüz ve örnek üzerinde bir model oluştururuz. Binlerce, hatta yüzbinlerce veri noktasına alt örnekleme, model çalışma sürelerini de istatistiksel geçerliliğini korurken mümkün kılar.

  • Sınıf dengesini korumak gerekiyorsa (veya bir sınıfın fazla / az örneklenmesi gerekiyorsa), örnekleme sırasında veri kümesini sınıflandırmak oldukça basittir.

Şekil 2.3: Örneklem

Avantajları

  • Hız: Tüm veri kümemiz üzerinde çalışmaya kıyasla, sadece bir örnek üzerinden çalışmak; çalışma sürelerini önemli ölçüde azaltabilir ve yineleme hızını artırabilir.
  • Prototipleme (İlk örnekleme): Sonunda modelimizi tüm veri kümesinde çalıştırmak zorunda kalsak bile, bu hiperparametreleri hassaslaştırmak ; modelimiz için iyi bir yol olabilir.
  • Paketler: Normal bir bellek içi veri kümesi üzerinde çalıştığımızdan, istediğimiz tüm R paketlerini kullanabiliriz.

Dezavantajları

  • Örnekleme: Alt örnekleme zor değildir, ancak geçerli olduğundan ve orijinal veri kümesinden yeterli sayıda nokta aldığımızdan emin olmak için dikkatle yapılması gerekir.
  • Ölçekleme: Daha sonra tam veri kümesinde çalıştırılacak bir şeyi prototiplemek için örnek ve model kullanıyorsak, prototip sürümümüzü tekrar tam veriye ölçeklendirmek için bir stratejimiz olması gerekir (veriyi hesaplamaya itmek gibi)
  • Toplam: İş Zekası (BI) görevleri, bir aydaki tüm satışların sayısı gibi, toplamlar hakkındaki soruları sık sık yanıtlar. Diğer stratejilerden biri, bu durumda genellikle daha iyi bir seçimdir.

Strateji 2: MapReduce

Bu stratejide, veriler ayrılabilir birimlere yığınlanır ve her yığın ayrı ayrı çekilir ve seri, paralel veya yeniden birleştirmeden sonra çalıştırırız. Bu strateji kavramsal olarak MapReduce algoritmasına benzer. Eldeki işe bağlı olarak, parçalar zaman periyotları, coğrafi birimler veya ayrı işletmeler, departmanlar, ürünler veya müşteri segmentleri gibi mantıklı olabilir.

Şekil 2.3: Mapreduce

Avantajları

  • Tam veri kümesi: Veri kümesinin tamamını kullanırız.
  • Paralelleştirme: Eğer parçaları ayrı ayrı çalıştırırsak, sorunu kapsamlı bir şekilde paralel olarak ele alabiliriz ve çalışma zamanlarını hızlandırmak için paralelleştirmeyi kullanırız.

Dezavantajları

  • Gerekli Parçalar: Veri ve yığının uygun olması için ayrılabilir parçalara sahip olmamız gerekir.
  • Tüm Verileri Çekmek: Belleğin yoğun olabileceği durumlarda tüm verierimizi çekmek zorunda kalırız.
  • Eski Veriler: Yerel makinemize bir sürüm kaydettiğimizden, güncel kalması için verilerimizin periyodik olarak yenilenmesi gerekebilir.

Strateji 3: Hesaplamayı Verilere Aktarma

Bu stratejide, verileri veritabanında sıkıştırırız ve yalnızca sıkıştırılmış veri kümesi veritabanından R‘a taşınır. Verileri R‘a çekmeden önce veritabanında özetleme veya filtreleme yaparak hızlandırmalar elde etmemiz genellikle mümkündür.

Bazen, dbplot ile histogram ve raster haritalarını hesaplama, modeldb ile bir model oluşturma ve tidypredict ile makine öğrenme modellerinden tahminler oluşturma gibi daha karmaşık işlemler de mümkündür.

Şekil 2.3: Sıkıştırma

Avantajları

  • Veritabanını Kullanma: En iyi veritabanlarının avantajlarından yararlanırız. (Bir sorguyu temel alarak verileri hızlı bir şekilde özetleme ve filtreleme gibi.)
  • Daha Fazla Bilgi, Daha Az Aktarım: Verileri tekrar R‘a çekmeden önce sıkıştırarak, tüm veri kümesini kullanırız. Ancak aktarım süreleri tüm veri kümesini taşımaktan çok daha azdır.

Dezavantajları

  • Veritabanı İşlemleri: Hangi veritabanını kullandığımıza bağlı olarak, bazı işlemler desteklenmiyor olabilir.
  • Veritabanı Hızı: Bazı bağlamlarda, veri analizi için sınırlayıcı faktör veritabanının hızıdır ve bu nedenle veritabanına daha fazla iş eklemek analistlerin yapmak istediği son şeydir.

2.4 Veri Seti

data=read.csv("C:/Users/emali/Desktop/cardio.csv",sep=";")
data=data[,-1] #ID değişkeni çıkarıldı.

Kaynak: https://www.kaggle.com/sulianova/cardiovascular-disease-dataset

Veri: Kardiyovasküler Hastalık veri setidir. Veri seti, 70.000 hasta verisi kaydı, 12 değişkenden oluşur. Tüm veri seti değerleri tıbbi muayene anında toplanmıştır.

Değişken Adı Açıklaması Değişken Türü
age Yaş Numerik
gender Cinsiyet 1:Kadın ; 2:Erkek
height Boy (cm) Numerik
weight Ağırlık (kg) Numerik
ap_hi Büyük Tansiyon Numerik
ap_lo Küçük Tansiyon Numerik
cholesterol Kolestrol 1:Normal ; 2:Normalin Üstünde ; 3:Normalin Çok Üstünde
gluc Glukoz Seviyesi 1:Normal ; 2:Normalin Üstünde ; 3:Normalin Çok Üstünde
smoke Sigara İçme Durumu 1:Sigara İçen ; 0:Sigara İçmeyen
alco Alkol Kullanım Durumu 1:Alkol İçen ; 0:Alkol İçmeyen
active Aktiflik Durmu 1:Aktif ; 0:Aktif Değil
cardio Hastalık Durumu 1:Var ; 0:Yok

2.4.1 Veri Setini Düzenleme

#Age
data$age=data$age/365
data$age=round(data$age,digits=0)
#Yaş değişkeni 365 ile bölünerek yıl olarak hesaplandı ve küsüratlar ortadan kaldırıldı.


#Bmi(Yeni Degisken)
data$bmi=data$weight/((data$height/100)^2)

#Gender
data$gender[data$gender==1]<-"Kadin"
data$gender[data$gender==2]<-"Erkek"

#Cholesterol
data$cholesterol[data$cholesterol==1]<-"Normal"
data$cholesterol[data$cholesterol==2]<-"Normalin Ustunde"
data$cholesterol[data$cholesterol==3]<-"Normalin Cok Ustunde"

#Glucose
data$gluc[data$gluc==1]<-"Normal"
data$gluc[data$gluc==2]<-"Normalin Ustunde"
data$gluc[data$gluc==3]<-"Normalin Cok Ustunde"

#Smoke
data$smoke[data$smoke==0]<-"Sigara icmeyen"
data$smoke[data$smoke==1]<-"Sigara icen"

#Alcohol
data$alco[data$alco==0]<-"Alkol icmeyen"
data$alco[data$alco==1]<-"Alkol icen"

#Active
data$active[data$active==0]<-"Aktif Degil"
data$active[data$active==1]<-"Aktif"

#Cardio
data$cardio[data$cardio==0]<-"Yok"
data$cardio[data$cardio==1]<-"Var"
  • Değişkenler üzerinde gerekli düzenlemeler yapıldı.

  • BMI (vücut kitle indeksi) adında yeni bir değişken eklendi.

data$gender<-as.factor(data$gender)
data$cholesterol<-as.factor(data$cholesterol)
data$gluc<-as.factor(data$gluc)
data$smoke<-as.factor(data$smoke)
data$alco<-as.factor(data$alco)
data$active<-as.factor(data$active)
data$cardio<-as.factor(data$cardio)

Gerekli değişkenler faktör olarak atandı.

plot_missing(data)

Eksik gözlemleri kontrol ettiğimizde, veride herhangi bir eksik gözlem olmadığını gördük.

2.4.2 Veriyi Özetlemek

head(data)
  age gender height weight ap_hi ap_lo          cholesterol   gluc
1  50  Erkek    168     62   110    80               Normal Normal
2  55  Kadin    156     85   140    90 Normalin Cok Ustunde Normal
3  52  Kadin    165     64   130    70 Normalin Cok Ustunde Normal
4  48  Erkek    169     82   150   100               Normal Normal
5  48  Kadin    156     56   100    60               Normal Normal
           smoke          alco      active cardio      bmi
1 Sigara icmeyen Alkol icmeyen       Aktif    Yok 21.96712
2 Sigara icmeyen Alkol icmeyen       Aktif    Var 34.92768
3 Sigara icmeyen Alkol icmeyen Aktif Degil    Var 23.50781
4 Sigara icmeyen Alkol icmeyen       Aktif    Var 28.71048
5 Sigara icmeyen Alkol icmeyen Aktif Degil    Yok 23.01118
 [ reached 'max' / getOption("max.print") -- omitted 1 rows ]
str(data)
'data.frame':   70000 obs. of  13 variables:
 $ age        : num  50 55 52 48 48 60 61 62 48 54 ...
 $ gender     : Factor w/ 2 levels "Erkek","Kadin": 1 2 2 1 2 2 2 1 2 2 ...
 $ height     : int  168 156 165 169 156 151 157 178 158 164 ...
 $ weight     : num  62 85 64 82 56 67 93 95 71 68 ...
 $ ap_hi      : int  110 140 130 150 100 120 130 130 110 110 ...
 $ ap_lo      : int  80 90 70 100 60 80 80 90 70 60 ...
 $ cholesterol: Factor w/ 3 levels "Normal","Normalin Cok Ustunde",..: 1 2 2 1 1 3 2 2 1 1 ...
 $ gluc       : Factor w/ 3 levels "Normal","Normalin Cok Ustunde",..: 1 1 1 1 1 3 1 2 1 1 ...
 $ smoke      : Factor w/ 2 levels "Sigara icen",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ alco       : Factor w/ 2 levels "Alkol icen","Alkol icmeyen": 2 2 2 2 2 2 2 2 2 2 ...
 $ active     : Factor w/ 2 levels "Aktif","Aktif Degil": 1 1 2 1 2 2 1 1 1 2 ...
 $ cardio     : Factor w/ 2 levels "Var","Yok": 2 1 1 1 2 2 2 1 2 2 ...
 $ bmi        : num  22 34.9 23.5 28.7 23 ...
summary(data)
      age          gender          height          weight      
 Min.   :30.00   Erkek:24470   Min.   : 55.0   Min.   : 10.00  
 1st Qu.:48.00   Kadin:45530   1st Qu.:159.0   1st Qu.: 65.00  
 Median :54.00                 Median :165.0   Median : 72.00  
 Mean   :53.34                 Mean   :164.4   Mean   : 74.21  
 3rd Qu.:58.00                 3rd Qu.:170.0   3rd Qu.: 82.00  
     ap_hi             ap_lo                        cholesterol   
 Min.   : -150.0   Min.   :  -70.00   Normal              :52385  
 1st Qu.:  120.0   1st Qu.:   80.00   Normalin Cok Ustunde: 8066  
 Median :  120.0   Median :   80.00   Normalin Ustunde    : 9549  
 Mean   :  128.8   Mean   :   96.63                               
 3rd Qu.:  140.0   3rd Qu.:   90.00                               
                   gluc                  smoke                  alco      
 Normal              :59479   Sigara icen   : 6169   Alkol icen   : 3764  
 Normalin Cok Ustunde: 5331   Sigara icmeyen:63831   Alkol icmeyen:66236  
 Normalin Ustunde    : 5190                                               
                                                                          
                                                                          
         active      cardio           bmi         
 Aktif      :56261   Var:34979   Min.   :  3.472  
 Aktif Degil:13739   Yok:35021   1st Qu.: 23.875  
                                 Median : 26.374  
                                 Mean   : 27.557  
                                 3rd Qu.: 30.222  
 [ reached getOption("max.print") -- omitted 1 row ]

3. Veriyi Okutma Teknikleri

3.1 data.frame Nedir?

Data.frame işlevi, R’ın modelleme yazılımının temel veri yapısı olarak kullanılan, matrislerin ve listelerin birçok özelliğini paylaşan, bağlı değişken koleksiyonları barındıran veri grupları oluşturmaya yarar. Data Frame’ler, tablo halinde verileri R’de saklamak için kullanılır. Bunlar, R’daki önemli nesne türlerinden biridir ve çeşitli istatistiksel modelleme uygulamalarında kullanılır. Data Frame’ler genellikle bir veri setinden(excel veya csv) read.table () veya read.csv () fonksiyonları kullanılarak okunur ve oluşturulur. Bununla birlikte, Data Frame’ler, data.frame () fonksiyonu ile açıkça oluşturulabilir. Veri çerçevesi, her sütunun bir değişkenin değerlerini ve her satırın her sütundan bir değer kümesini içerdiği bir tablo veya iki boyutlu dizi benzeri bir yapıdır.

Aşağıda bir veri çerçevesinin özellikleri verilmiştir.

  • Sütun adları boş olmamalıdır.
  • Satır adları benzersiz olmalıdır.
  • Bir veri çerçevesinde saklanan veriler sayısal, faktör veya karakter tipinde olabilir.
  • Her sütun aynı sayıda veri öğesi içermelidir.

3.2 data.table Nedir?

data.table, R tabanında veri depolamak için standart veri yapısı olan data.frame’in gelişmiş bir sürümünü sağlayan bir R paketidir. Data.frame’in aksine, karakter türündeki sütunlar hiçbir zaman varsayılan olarak faktörlere dönüştürülmez. Bu kadar popüler olmasının nedeni, daha büyük veriler üzerinde yürütme hızı ve kısa sözdizimidir. Böylece etkili bir şekilde daha az kod yazılır ve çok daha hızlı işlemler uygulanır. Data.table, data.frame’den biraz farklı bir sözdizimi sağlasa da, oldukça sezgiseldir.

3.3 data.table ve data.frame Hız Testi

set.seed(100)
m <- data.frame(matrix(runif(10000000), nrow=1000000))
write.csv(m, 'm2.csv', row.names = F)

(data_frame=system.time({m_df <- read.csv('m2.csv')}))
   user  system elapsed 
  40.46    0.98   41.90 
(data_table=system.time({m_dt <- fread('m2.csv')}))
   user  system elapsed 
   0.53    0.14    0.40 

Çekilen iki rastgele örneklemde performans süreleri hesaplanmıştır. Data table üzerindeki performansın daha etkili olduğu görülmektedir. Baz alınan süreler arasındaki fark dosya büyüklüğü ile doğru oranda artış gösterecektir.

3.4 dplyr vs data.table

Data.table ve dplyr, her ikisi de veri çerçevelerinin daha kolay ve verimli bir şekilde değiştirilmesini amaçlayan iki R paketidir. Ancak birçok işlevi ortak olsada, felsefeleri oldukça farklıdır. Data.table birçok işlemi çok kısa ve tutarlı bir ifadede birleştirmeye izin verir. dplyr en yaygın işlemlere karşılık gelen anahtar fiillere dayanmaktadır. data.table paketinin bağımlılığı yoktur, oysa dplyr tidyverse’in bir parçasıdır. Örneğin, data.table verileri okuma, yazma veya yeniden şekillendirme işlevlerini içerirken, dplyr bu görevleri readr veya tidyr gibi tamamlayıcı paketlere devreder. Öte yandan, data.table yerel bellek içi verilerin işlenmesine odaklanır, ancak dplyr bir veritabanı arka ucu sunar. data table‘da nesneler “referans olarak” değiştirilebilir. Bu, verilerin değiştirileceği ancak kopyalanmayacağı anlamına gelir, bu da RAM gereksinimlerini en aza indirir. Dplyr’da ise, bellek yönetimi, paralellik ve optimizasyon, data.table’a performans açısından avantaj sağlar.

data.table’ın yazarı Matt Dowle:

data.table, kullanım kolaylığı, rahatlık ve programlama hızı için sözdizimi ve özellik geliştirmeleri ile R’ın veri çerçevesinin yüksek performanslı bir sürümünü sağlar.”

dplyr’ın yazarı Hadley Wickham:

dplyr, en yaygın veri işleme zorluklarını çözmenize yardımcı olan tutarlı bir fiil kümesi sağlayan bir veri işleme dilbilgisidir.”

3.4.1 dplyr vs data.table Uygulama

data("AutoClaims") #veri setinin yüklenmesi
db <- AutoClaims #veri setine yeni bir isim atanması
db <- data.table(db) #data.table'a dönüştürme

Verinin 6773 satırı ve 5 sütunu vardır.

head(db)
      STATE CLASS GENDER AGE    PAID
1: STATE 14   C6       M  97 1134.44
2: STATE 15   C6       M  96 3761.24
3: STATE 15   C11      M  95 7842.31
4: STATE 15   F6       F  95 2384.67
5: STATE 15   F6       M  95  650.00
6: STATE 15   F6       M  95  391.12

3.4.2 En Sık Kullanılan 10 Veri İşleme İşlevi

  1. Satırlara Göre Filtrelemek

79 yaş ve altı erkekler için filtre uygulandı.

# db[AGE <= 79 & GENDER == "M"] #datatable
# db %>% filter(AGE <= 79 & GENDER == "M") #dplyr
  1. Sütunlara Göre Seçim Yapmak

GENDER, AGE ve PAID sütunlarını seçelim.

# db[, .(GENDER, AGE, PAID)] #datatable
# db %>% select(GENDER, AGE, PAID) #dplyr
  1. Yeni Sütunlar Eklemek

8,63 Dolar/TL dönüşüm oranını kullanarak PAID’yi Dolardan TL’ye çevirelim. Ortaya çıkan yeni değişken veri kümesine eklenir.

# db[, PAID.IN.TL := PAID * 8.63] #datatable
# db %>% mutate(PAID.IN.TL = PAID * 8.63) #dplyr
  1. Sütun Silmek

Yeni oluşturulan değişkeni silelim.

# db[, !c("PAID.IN.TL")] #datatable
# db[, PAID.IN.TL := NULL] #datatable (alternatif yol)
# select(db, -PAID.IN.TL) #dplyr
  1. Yeni Sütun Oluşturmak

Yeni bir değişken oluşturup ve mevcut olanları bırakalım. Sonuç olarak, veri kümesi yalnızca yeni bir değişkene sahip olacaktır.

# db[, .(PAID.IN.TL = PAID * 8.63)] #datatable
# db %>% transmute(PAID.IN.TL = PAID * 8.63) #dplyr
  1. Sütuna Göre Özetlemek

Ödenen ortalama sigorta tazminatı ne kadardır? Aşağıdaki kod verileri toplar ve AVG.PAID adlı tek bir kayıt döndürür.

# db[, .(AVG.PAID = mean(PAID))] #datatable
# db %>% summarise(AVG.PAID = mean(PAID)) #dplyr
  1. Değişkeni Yeniden Adlandırmak

“data.table” ile eski isimleri ve ardından yeni isimleri referans alan “setnames” fonksiyonunu kullanırız. “dplyr” ile sıra tersine çevrilir.

# setnames(db, c("GENDER", "CLASS"), c("gender", "class")) #dt
# db %>% rename("gender" = "GENDER", "class" = "CLASS") #dplyr
  1. Verileri Artan Veya Azalan Düzende Sıralamak

data.table’daki “setorder” ve dplyr’daki “arrange” işlevini kullanarak verileri artan ve azalan düzende sıralayabiliriz.

# setorder(db, PAID) #datatable artan sıralama
# setorder(db, -PAID) #datatable azalan sıralama
# db %>% arrange(PAID) #dplyr artan sıralama
# db %>% arrange(desc(PAID)) #dplyr azalan sıralama
  1. Sütuna Göre Gruplandırmak

Verileri tek başına gruplamak hiçbir anlam ifade etmez; bunu başka bir işlevle birleştirmelisiniz. Örneğin “State” değişkenine göre gruplandırmalı ve verileri özetlemeli veya verileri filtrelemelisiniz.

# db[, .(mean.paid.by.state = mean(PAID)), by = "STATE"]
# db %>% group_by(STATE) %>%
#   summarize(mean.paid.by.state = mean(PAID))
  1. Gözlemleri Saymak

dplyr için “n()” işlevini ve data.table için “.N” işlevini kullanarak her sınıf için kaç gözlemimiz olduğunu sayabiliriz.

# db[, .N, by= "class"] #datatable
# db %>% #dplyr
#  group_by(class) %>%
#  summarise(n())

dplyr ve data.table karşılaştırıldı. 10 ortak işlev ve zincirleme işlevler kullandık. Her iki kütüphaneyle de yapabilecek çok işlem mevcuttur. Data.table, dplyr’dan daha kısa sözdizimi kullanır, ancak genellikle daha ayrıntılı ve karmaşıktır. Bellek ve hız önemli mi? Karmaşık raporlar ve dashboardlar oluştururken ve özellikle çok büyük veri kümeleriyle çalışırken data.table’ın belirgin avantajları vardır.

3.5 Sparklyr Paketi

Sparklyr, “R” ve “Apache Spark” arasında bir arayüz sağlayan, R’daki büyük verileri işlemek için kullanılan açık kaynaklı küme hesaplama mantığında çalışan bir pakettir. Sparklyr kütüphanesi ile büyük veriyi bir Spark kümesi içerisinde analiz edebilirsiniz. Bu paket, hem bellekte hem de bellek dışında veri çerçevesi nesneleriyle çalışmak için popüler bir araç olan dplyr paketi için eksiksiz bir zemin oluşturmaktadır. R kodunu Spark SQL’e çevirmek için dplyr kullanabilirsiniz. Sparklyr ayrıca MLlib‘i destekler, böylece Spark’ta verileriniz üzerinde sınıflandırma, regresyon, küme, karar ağaçları ve daha birçok makine öğrenimi algoritmasını çalıştırabilirsiniz. MLlib, Apache Spark’ın ölçeklenebilir makine öğrenimi kütüphanesidir. Java, Scala, Python programlama dilllerinde de kullanılabilir. Sparklyr ile, geleneksel olarak R belleğini aşan büyük miktarda veriyi analiz edebilir, daha fazla görselleştirme ve dokümantasyon için Spark’tan R’a sonuçlar toplayabilirsiniz.

3.5.1 MapReduce ve Spark Karşılaştırması

Spark’ın ilk çıktığı zamanlarda Hadoop ile bolca karşılaştırılmış olsa da, ikisi birbirinden farklı teknolojilerdir. Spark’ın ana işlevi veri analizidir ve bir depolama birimi yoktur. Buna karşın Hadoop’un HDFS adı altında bir dosya sistemi, depolama birimi vardır. Hadoop veri analizi çözümü olan MapReduce’u da içeren geniş bir framework’tür.

MapReduce’da sadece HDFS dosya sisteminde yani disk üzerinde bulunan veri üzerinde analiz yapılabilirken Spark’ta HDFS dahil olmak üzere bir çok veri kaynağı (İlişkisel veritabanları, NoSql, Kafka, elasticsearch vb.) üzerinde analiz gerçekleştirilebilir. Spark bu analizleri yaparken ram üzerinde (in-memory) yapar, belleklerin yetmediği durumlarda diskleri de kullanır. Hızının sırrı da bellekleri kullanabilmesinde yatar. Bu yüzden Spark, Hadoop’tan 100 kat daha hızlı olduğunu iddia eder.

Spark, büyük veri ekosistemindeki birçok teknoloji gibi dağıtık mimariyi desteklediği için cluster’daki tüm sunucular üzerinde aynı anda dağıtık bir şekilde hesaplama yapar. Basit bir örnek verecek olursak cluster’ımızda her birinin 128GB ram’i olan 10 sunucumuz varsa, hesaplama yaparken 1 TB’ın üzerinde bir ram gücünü kullandığı anlamına gelir. Ram ile birlikte tüm bu sunucuların işlemci gücü de kullanılır. Spark’la birlikte kullanılan makine öğrenmesi algoritmaları için de geçerlidir bu hız. Mesela TensorFlow ve PyTorch gibi kütüphanelerle yazılan makine öğrenmesi algoritmaları tek bir ortamda çalıştırabilirken, Spark ile makine öğrenmesi uygulaması geliştirildiğinde tüm cluster’daki sunucularda çalıştırıldığı için daha hızlı olabilmektedir. Bu bağlamda Spark paralel işlem gücünü makine öğrenmesi alanına da uygulamıştır.

Sonuç

Apache Spark hem batch hem de real-time analize izin veren bunun yanı sıra makine öğrenmesi ve graf analizi ve sql gibi veriyle ilgili bir çok alanı destekleyen açık kaynak bir büyük veri aracıdır. Apache Spark bu kadar özelliğine rağmen rakipsiz değildir. Flink gibi güçlü rakipleri vardır. Arkasında güçlü bir topluluğun olmasıyla, birçok programlama diliyle analiz yapılabilmesiyle, streaming analizlerin öneminin her geçen gün artmasıyla ve makine öğrenmesi modülünün sürekli geliştirilmesiyle Apache Spark’ın sektördeki yeri sağlamlaşmaktadır.

3.5.2 Kurulum ve Spark Bağlantısının Oluşturulması

spark_install(version = "2.1.0")
sc <- spark_connect(master = "local", spark_home = spark_home_dir(version = "2.1.0"))

Spark bağlantısını oluşturduk.

3.5.3 Verinin Spark’a Taşınması

src_tbls(sc)
character(0)

Henüz Spark ortamına bir veri aktarmadık. Alınan çıktıda da bunu görüyoruz.

copy_to(sc, data , "cardio_spark")
# Source: spark<cardio_spark> [?? x 13]
     age gender height weight ap_hi ap_lo cholesterol gluc  smoke alco  active
   <dbl> <chr>   <int>  <dbl> <int> <int> <chr>       <chr> <chr> <chr> <chr> 
 1    50 Erkek     168     62   110    80 Normal      Norm~ Siga~ Alko~ Aktif 
 2    55 Kadin     156     85   140    90 Normalin C~ Norm~ Siga~ Alko~ Aktif 
 3    52 Kadin     165     64   130    70 Normalin C~ Norm~ Siga~ Alko~ Aktif~
 4    48 Erkek     169     82   150   100 Normal      Norm~ Siga~ Alko~ Aktif 
 5    48 Kadin     156     56   100    60 Normal      Norm~ Siga~ Alko~ Aktif~
 6    60 Kadin     151     67   120    80 Normalin U~ Norm~ Siga~ Alko~ Aktif~
 7    61 Kadin     157     93   130    80 Normalin C~ Norm~ Siga~ Alko~ Aktif 
 8    62 Erkek     178     95   130    90 Normalin C~ Norm~ Siga~ Alko~ Aktif 
 9    48 Kadin     158     71   110    70 Normal      Norm~ Siga~ Alko~ Aktif 
10    54 Kadin     164     68   110    60 Normal      Norm~ Siga~ Alko~ Aktif~
# ... with more rows, and 2 more variables: cardio <chr>, bmi <dbl>
tbl_cache
function (sc, name, force = TRUE) 
{
    countColumns <- function(sc, name) {
        sql <- sprintf("SELECT * FROM %s LIMIT 0", tbl_quote_name(sc, 
            name))
        sdf <- invoke(hive_context(sc), "sql", sql)
        length(invoke(sdf, "columns"))
    }
    if (spark_version(sc) < "2.0.0" && countColumns(sc, name) >= 
        1000) {
        tbl_cache_sdf(sc, name, force)
    }
    else {
        tbl_cache_sql(sc, name, force)
    }
    invisible(NULL)
}
<bytecode: 0x0000000041d733d0>
<environment: namespace:sparklyr>

Spark ortamına veriyi tanıttık. Şimdi bir önceki chunkta uyguladığımız “src_tbls(sc)” kodunu bir kez daha çalıştırıp bunu görebiliriz.

src_tbls(sc)
[1] "cardio_spark"

Görüldüğü gibi Spark ortamına verimizi taşıdık. Yapmamız gereken üstüne yazdırmak olacak.

f_tbl <- copy_to(sc, data, 
                 "cardio_spark", overwrite = TRUE)

head(f_tbl)
# Source: spark<?> [?? x 13]
    age gender height weight ap_hi ap_lo cholesterol gluc  smoke alco  active
  <dbl> <chr>   <int>  <dbl> <int> <int> <chr>       <chr> <chr> <chr> <chr> 
1    50 Erkek     168     62   110    80 Normal      Norm~ Siga~ Alko~ Aktif 
2    55 Kadin     156     85   140    90 Normalin C~ Norm~ Siga~ Alko~ Aktif 
3    52 Kadin     165     64   130    70 Normalin C~ Norm~ Siga~ Alko~ Aktif~
4    48 Erkek     169     82   150   100 Normal      Norm~ Siga~ Alko~ Aktif 
5    48 Kadin     156     56   100    60 Normal      Norm~ Siga~ Alko~ Aktif~
6    60 Kadin     151     67   120    80 Normalin U~ Norm~ Siga~ Alko~ Aktif~
# ... with 2 more variables: cardio <chr>, bmi <dbl>

Veriyi başarılı bir şekilde spark ortamına taşıdık ve kopyaladık. Ardından head() komutu ile verinin ilk 6 gözlemini içeren kısmı inceleyebiliriz. Spark ortamına taşıdığımız veri ile çalışabilmek için “dplyr” paketini kullanmamız gerekecek. R içerisindeki tüm fonksiyonlar çalışmayacaktır.

#f_tbl$cholesterol
#str(f_tbl)
#summary(f_tbl)
#nrow(f_tbl)
#apply(f_tbl, 2, mean)

R içerisindeki her fonksiyon çalışmıyor. Bu fonksiyonlar çalıştırılınca çıktısı “NULL” olacaktır. Yapılması gereken dplyr paketi ile çalışmaktır.

a<-f_tbl %>% select(height)
head(a)
# Source: spark<?> [?? x 1]
  height
   <int>
1    168
2    156
3    165
4    169
5    156
6    151

Dplyr paketini kullanarak kısa bir kod yazdık. Böylelikle çalıştığı ve analiz yapabilmek için uygun olduğu görülüyor.

select(f_tbl, age, smoke, bmi)
# Source: spark<?> [?? x 3]
     age smoke            bmi
   <dbl> <chr>          <dbl>
 1    50 Sigara icmeyen  22.0
 2    55 Sigara icmeyen  34.9
 3    52 Sigara icmeyen  23.5
 4    48 Sigara icmeyen  28.7
 5    48 Sigara icmeyen  23.0
 6    60 Sigara icmeyen  29.4
 7    61 Sigara icmeyen  37.7
 8    62 Sigara icmeyen  30.0
 9    48 Sigara icmeyen  28.4
10    54 Sigara icmeyen  25.3
# ... with more rows

Select komutunu kullanarak istediğimiz değişkenleri(sütunları) seçebiliriz.

summarise(f_tbl, 
          ortalama = mean(bmi),
          standart_sapma = sd(bmi), 
          varyans = var(bmi))
# Source: spark<?> [?? x 3]
  ortalama standart_sapma varyans
     <dbl>          <dbl>   <dbl>
1     27.6           6.09    37.1

Dplyr paketini kullanarak veri üzerinde özet istatistikler alabiliriz.

f_tbl %>% 
  group_by(smoke) %>% 
  summarise(n=n())
# Source: spark<?> [?? x 2]
  smoke              n
  <chr>          <dbl>
1 Sigara icmeyen 63831
2 Sigara icen     6169
#f <- f_tbl %>% 
#group_by(cholesterol) %>% 
#summarise(n=n())

#f$n

Dplyr kullanılarak yeni bir veri kümesi oluşturulmak istenirse, bu durumda “collect” komutu kullanılmalıdır. Aksi takdirde çalıştırılan kodun çıktısı “NULL” olacaktır.

f <- f_tbl %>% 
  group_by(cholesterol) %>% 
  summarise(n=n()) %>%
  collect()
f$n
[1]  8066 52385  9549

Spark ortamına taşınan veriler üzerinde örnek teşkil etmesi adına dplyr paketini kullanarak bazı çalışmalar yapılmıştır. Bununla birlikte SQL sorgusu göndermekte mümkündür.

dbGetQuery(sc, "show databases")
  namespace
1   default

SQL sorgusu göndererek Spark ortamına taşıdığımız verileri görebiliyoruz.

# db<-dbGetQuery(sc, 'select age, bmi, smoke from cardio_spark where age > 50
# and bmi > 25') head(db)

# dbGetQuery(sc, 'select count(*) as n from cardio_spark where age > 50 and bmi
# > 25')

Daha önce dplyr ile yaptılan çalışmalar gibi SQL sorgusu ile veri üzerinde çalışılabilir. Aynı veri setinden “ggplot” paketi kullanarak spark üzerinde grafik oluşturulabilir.

# data2 <- f_tbl %>% filter(bmi>35) %>% select(cardio,active) %>% collect()

# ggplot(data2) + aes(x = cardio, fill = active) + geom_bar(position = 'dodge')
# + scale_fill_brewer(palette = 'Paired') + labs(title =
# 'Aktiflik-Cardio',subtitle ='Çubuk Grafiği') + ggthemes::theme_wsj() +
# theme(legend.position = 'top')

4. Büyük Veri Görselleştirme

Veri görselleştirme; verilerin, grafiksel çizelgeler, şekiller ve sütunlar aracılığıyla bilgilerin sunumudur. Doğru zamanda doğru kararları vermemize yardımcı olacak bir dizi içgörü sunar. Stratejik planlamalar yapmak için çok ihtiyaç duyulan bir araçtır. Aslında tam bir karar destek sistemi diyebiliriz. Büyük verilerle uğraştığımızda, veri görselleştirmelerinden aşağıdakiler gibi birçok şekilde yararlanabiliriz:

  • Değişkenlerin dağılım özelliklerini anlamak,
  • Veri girişi sorunlarını tespit etmek,
  • Verilerdeki aykırı değerlerin belirlenmesi,
  • Değişkenler arasındaki ilişkileri anlamak,
  • Veri analizi için uygun değişkenlerin seçilmesi,
  • Tahmine dayalı modellerin sonuçlarını incelemek,
  • Sonuçları çeşitli kitlelere iletmek.

Etkili görselleştirmeler geliştirmek, hedeflerin belirlenmesini ve veri analizinin net bir şekilde tasarlanmasını gerektirir. Bazen verilerle ilgili bazı soruların yanıtlarını zaten biliyor olabiliriz; diğer durumlarda, veri analizinin sonraki adımlarına ilişkin daha iyi içgörüler oluşturmak için daha fazla araştırma yapmak ve verileri anlamak isteyebiliriz. Bu süreçte kullanılacak değişken türleri, eksenler, etiketler, lejantlar, renkler vb. birçok unsuru göz önünde bulundurmamız gerekiyor. Ayrıca, görselleştirmeyi belirli bir kitleye sunmayı hedefliyorsak, görselleştirmenin hedef kitle için kullanılabilirliğini ve yorumlanabilirliğini de dikkate almamız gerekir. R’da, bu görselleştirmelerin neredeyse tamamı çok kolay bir şekilde oluşturulabilir.

Etkili bir veri görselleştirmenin geliştirilmesi tipik olarak aşağıdaki adımları içerir:

  • Veri görselleştirmenin amacını belirlemek
  • Verileri hazırlamak
  • Veri görselleştirme hedefine göre ideal görselleştirme aracını belirlemek
  • Görselleştirmeyi üretmek
  • Görselleştirmedeki bilgileri yorumlamak ve hedef kitleye sunmak

Büyük verileri organize etmemize, değişkenleri yorumlamamıza ve tahmine dayalı modeller için potansiyel değişkenleri belirlememize yardımcı olabilecek R’deki veri görselleştirme araçlarını inceleyeceğiz. 1. bölümde, ggplot2 paketini kullanarak çeşitli veri görselleştirmeleri yapılacaktır. 2. bölümde, plotly kullanarak görselleştirmeler yapılacaktır.

Not: Oluşturulan görsellerde filtreleme, koşullu grafikler ve örneklem kullanma gibi teknikler kullanılmıştır. Bunun sebebi büyük verileri görselleştirme aşamasında, ilgilendiğimiz alan veya kısıtlara göre hareket etme imkanı sağlayan, aynı zamanda daha hızlı avantajını getiren tekniklerdir.

set.seed(101)
data_sample = data[sample(nrow(data), 500), ]

4.1 ggplot2

ggplot2 R’daki çok yönlü bir görselleştirme paketidir. Ayrıca, küçük veya büyük veriler için çeşitli görselleştirmeler oluşturmak için basit bir grafik grameri uygular. Bu, minimum miktarda ayarlama ve ince ayar ile kolayca yayınlar ve sunumlar için yüksek kaliteli grafikler oluşturmayı sağlar.

4.1.1 Çubuk Grafiği

Çubuk grafiği, oldukça sık kullanılan grafik türlerinden biridir ve birbirinden farklı kategoriler-gruplar için sayı, frekans vb. bilgileri göstermek ve kıyaslamak için kullanılır. Çubuk grafiklerde yükseklik veya uzunluk, temsil ettikleri verinin değeriyle orantılı olacak şekilde oluşturulur. X ekseni (yatay eksen) farklı kategorileri temsil ettiği için bir ölçeğe sahip değildir. Y ekseni (dikey eksen) bir ölçeğe sahiptir ve ölçüm birimleri bu eksende gösterilir. Çubuklar kategori sayısına, kategori etiketlerinin uzunluğuna veya karmaşıklığına bağlı olarak dikey veya yatay olarak çizilebilir. Çubuk grafiklerin oluşturulabileceği çeşitli yolların olması, bu grafik türünün oldukça esnek olmasını sağlar.

d <- data %>%
    dplyr::group_by(cholesterol) %>%
    dplyr::summarise(frekans = n()) %>%
    dplyr::mutate(kolesterol = cholesterol, Ratio = frekans/sum(frekans), label = percent(Ratio %>%
        round(2)))

g <- ggplot(d, aes(x = kolesterol, y = Ratio, label = label, fill = kolesterol)) +
    geom_bar(stat = "identity", fill = "indianred3", color = "black") + geom_text(vjust = -0.3)
g

ggplot(data_sample) + aes(x = cholesterol, fill = cardio) + geom_bar(position = "dodge") +
    scale_fill_brewer(palette = "Accent") + labs(title = "Cardio-Aktif olma durumu Cubuk Grafiği") +
    ggthemes::theme_hc() + theme(legend.position = "top", axis.text.x = element_text(angle = 55,
    vjust = 0.6)) + facet_wrap(vars(active), scales = "free")

Çubuk grafiklerine alternatif olarak kullanılabilecek olan nokta grafikleri de mevcuttur. Kullanım alanlarına göre uyarlamak mümkündür. Temel olarak geom_point() fonksiyonu iki sayısal değişkenin aralarındaki ilişikiyi görmek için(korelasyon) kullanılsa da, yapılacak bazı dönüşümler ile farklı şekillerde bize görselleştirme fırsatları sunabilir. Aşağıda bulunan grafikler veride bir filtreleme işlemi kullanılarak ve her defasında grafiğe yeni tanımlamalar yapılarak düzenlenmiştir.

data(gapminder, package = "gapminder")

library(dplyr)
plotdata <- gapminder %>%
    filter(continent == "Europe" & year == 2007)
ggplot(plotdata, aes(x = lifeExp, y = country)) + geom_point()

ggplot(plotdata, aes(x = lifeExp, y = reorder(country, lifeExp))) + geom_point()

ggplot(plotdata, aes(x = lifeExp, y = reorder(country, lifeExp))) + geom_point(color = "blue",
    size = 2) + geom_segment(aes(x = 40, xend = lifeExp, y = reorder(country, lifeExp),
    yend = reorder(country, lifeExp)), color = "lightgrey") + labs(x = "Life Expectancy (years)",
    y = "", title = "Life Expectancy by Country", subtitle = "GapMinder data for Europe - 2007") +
    theme_minimal() + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())

4.1.2 Violin Grafiği

Violin (keman) grafiği verilerin dağılımını ve olasılık yoğunluğunu görselleştirmek için en efektif yöntemlerden birisidir. Violin grafiği box plot ve KDE’nin kombinasyonundan doğmuştur. Box plot, görsel basitliği ve verilerdeki değerlerin nasıl dağıldığına ilişkin önemli ayrıntıları gizleme eğiliminde olduğundan, değişken değerlerinin dağılımının gösterilmesinde sınırları bulunmaktadır.

mpg$class = with(mpg, reorder(class, hwy, median))

p <- mpg %>%
    ggplot(aes(x = class, y = hwy, fill = class)) + geom_violin() + xlab("class") +
    theme(legend.position = "none") + xlab("")
p

4.1.3 Histogram ve Yoğunluk Grafiği

Histogram, sayısal verilerin dağılımının grafik bir sunumu ve sürekli değişkenin (niceliksel değişken) olasılık dağılımının bir tahminidir. Bir çeşit çubuk grafik olan bu gösterim şekli Karl Pearson tarafından literatüre kazandırılmıştır (Pearson, 1920). Histogram oluşturmak için öncelikle değer aralığının belirlenmesi gerekir. Bunun için veriler küçükten büyüğe sıralanır. Açıklık değerini bulmak için veri setindeki en büyük sayıdan en küçüğü çıkartılır. Oluşturmak istenen grup sayısı tespit edilir. Daha sonra veri grubunun genişliği bulunur.Genişlik bulunurken açıklık değeri grup sayısına bölünür. Elde edilen genişlik bir üstteki doğal sayı olarak alınır. Histogramlar, verilerin sahip olduğu dağılımın yoğunluğunu gösterir ve değişkenin olasılık yoğunluk fonksiyonunu anlamak için bir tahmin verir. Olasılık yoğunluğu için kullanılan histogramın toplam alanı daima 1’e normalize edilir. X ekseni üzerindeki aralıkların uzunluğu 1 ise, histogram göreceli frekans aralığı ile aynıdır. İlave olarak, yoğunluk tahmini histograma bir alternatif olarak çizilebilir ve genellikle bir kutu kümesi yerine eğri olarak gösterilir (Howitt ve Cramer, 2008). Histogram, incelemesi zaman alacak büyük veri kümelerini grafiksel olarak hızlı biçimde özetler. Histogram kullanımının bir başka faydası, bir üretim işlemi sonuçlarını olması gereken özellik sınırlarıyla karşılaştırır. Histograma süreçleri belirten sınırlar eklenirse, mevcut işlemin “iyi” ürünleri üretip üretemediği hızlı bir şekilde belirlenebilir.

ggplot(data_sample) + aes(x = weight) + geom_histogram(bins = 30L, fill = "darkblue",
    position = "identity", color = "orange", alpha = 0.6, ) + ggthemes::theme_fivethirtyeight()

g <- ggplot(mpg, aes(cty))
g + geom_density(aes(fill = factor(cyl)), alpha = 0.8) + labs(title = "Density Plot",
    subtitle = "Silindir Sayısına Göre Şehir İçi Performans", caption = "Mpg", x = "City Mileage",
    fill = "Cylinders")

4.1.4 Kutu Grafiği

Kutu grafiği, verilerin dağılımıyla ilgili açıklayıcı bir grafik sunumunu verir. Kutu birinci (Q1) ve üçüncü kuartillerin (Q3) değerlerini, kutunun ortasındaki ağır çizgi medyanı, bıyıklar da çeyreğin değerlerini ve çeyrekler arası aralığın yaklaşık 1,5 katını gösterir. Kutu grafikleri bir değişkene ait verilerin sıklık dağılımını göstermek için kullanılır. Dağılımın şekli, merkezi eğilimi ve değişkenlerin yayılım durumunu tek grafikte göstermesi nedeniyle kullanışlıdır. Kutu grafiği, çeyreklere dayalı grafiksel açıklamadır. Bir kutu grafiğini çizmek için, en küçük değer, alt çeyrek (Q1), ortanca, üst çeyrek (Q3) ve en büyük değerin bulunması gerekir.

Kutu grafiğinde;

  • Kutunun uç noktaları Q1 ve Q3’ te yer alır.
  • Kutunun uzunluğu Q3-Q1 olarak hesaplanır. Bu fark, aynı zamanda verilerin ortadaki yarısının yayılma ölçüsünü ifade eder.
  • Ortanca (median), kutunun içinde çizgi ile gösterilir.
  • Kutu dışındaki iki çizgi, alt uç değer ve üst uç değere kadar uzatılır.

mpg %>%
    mutate(class = fct_reorder(class, hwy, .fun = "median")) %>%
    ggplot(aes(x = reorder(class, hwy), y = hwy, fill = class)) + geom_boxplot() +
    xlab("class") + theme(legend.position = "none") + xlab("")

4.1.5 Korelasyonlarin İncelenmesi Ve Korelasyon Tablosu

Korelasyon temel anlamda iki değişken arasındaki ilişkiyi göstermek için kullanılır. Olasılık kuramı ve istatistikte iki rassal değişken arasındaki doğrusal ilişkinin yönünü ve gücünü belirtir. Genel istatistiksel kullanımda korelasyon, bağımsızlık durumundan ne kadar uzaklaşıldığını gösterir. Aşağıda verilen korelasyon grafiği bir çok grafik içerisinden seçilmiştir. Mevcut olan korelasyon tablosu ve grafikleri R kütüphanelerinde fazlasıyla çeşitli bulunmaktadır.

corr <- round(cor(mtcars), 1)
ggcorrplot(corr, hc.order = TRUE, type = "lower", lab = TRUE, lab_size = 3, method = "circle",
    colors = c("tomato2", "white", "springgreen3"), title = "Correlogram of mtcars",
    ggtheme = theme_bw)

4.1.6 Saçılım Grafiği

Bilimsel ve mühendislik literatüründe karşılaşılan en yaygın grafiksel gösteri türüdür. Saçılım grafiği, her bir eksende bir değişken olan sayısal veri çiftlerinin (x,y), aralarındaki ilişkiyi gösterir. Saçılım dağılımında, bir x ekseni (yatay eksen) ve bir y ekseni (dikey eksen) ve bir dizi nokta (veriler) bulunur. Dağılım grafiğindeki her nokta, veri kümesindeki bir gözlemi temsil eder. Dağılım çizgisi üzerindeki nokta konumu, x ve y değerlerini temsil eder. Aşağıdaki saçılım grafikleri, gelişmiş bazı özellikler kullanılarak yapılmıştır.

ggplot(mtcars, aes(x = wt, y = mpg, colour = factor(cyl))) + geom_point()

Birimleri Grafige Eklemek

ggplot(mtcars, aes(x = wt, y = mpg, fill = cyl)) + geom_point() + geom_label(label = rownames(mtcars),
    nudge_x = 0.25, nudge_y = 0.2) + geom_smooth(method = lm, se = TRUE)

Marjinlere Dagilim Eklemek

g <- ggplot(mtcars, aes(x = wt, y = mpg, fill = cyl)) + geom_point() + geom_label(label = rownames(mtcars),
    nudge_x = 0.25, nudge_y = 0.2) + geom_smooth(method = lm, se = FALSE)


ggMarginal(g, type = "histogram", fill = "slateblue")

ggMarginal(g, type = "density")

ggMarginal(g, type = "boxplot")

4.2 Plotly

plotly paketi kullanarak daha interaktif görselleştirmeler yapılabilir. Çizgi grafikleri, dağılım grafikleri, alan grafikleri, çubuk grafikler, hata çubukları, kutu grafikleri, histogramlar, ısı haritaları, alt grafikler, çoklu eksenler ve 3B (WebGL tabanlı) grafikler oluşturma fırsatı sunar. Aşağıdaki grafiklerin bir kısmında verinin tamamını kullanarak oluşturulduğunu göreceksiniz. Sonrasında rastgele çekilen örneklem ile oluşturulan grafiğin daha anlaşılır olduğu ortaya çıkacaktır. Ggplot paketinde bahsettiğimiz grafik türlerinin bir kısmını göreceksiniz.

plot_ly(data = data, x = ~bmi, y = ~weight)

Tüm veriyi kullanarak oluşturulan saçılım grafiğini yorumlamak ve anlamak zor olabilir. Çalışılan veri büyüdükçe bu durum daha zor hale gelecektir.

plot_ly(data = data_sample, x = ~bmi, y = ~weight)

Bu grafikte, bir önceki grafikten farklı olarak çekilen rastgele örneklem kullanılmıştır. Görüldüğü üzere bu yöntem ile grafiğin yorumlanabilirliği ve anlamı artmıştır.

mpg$cyl = as.factor(mpg$cyl)
fig <- mpg
fig <- fig %>%
    count(class, cyl)
fig <- fig %>%
    plot_ly(x = ~class, y = ~n, color = ~cyl)
fig

Gruplama yöntemiyle oluşturulan bir çubuk grafiğini görüyoruz.

plot_ly(mpg, y = ~hwy, color = ~class, type = "box")

Plotly paketi kullanılarak oluşturulan boxplot grafiği ile istatistiksel değerleri görmek mümkündür.

df <- gapminder
fig <- df %>%
    plot_ly(x = ~gdpPercap, y = ~lifeExp, size = ~pop, color = ~continent, frame = ~year,
        text = ~country, hoverinfo = "text", type = "scatter", mode = "markers")
fig <- fig %>%
    layout(xaxis = list(type = "log"))
fig <- fig %>%
    animation_opts(1000, easing = "elastic", redraw = FALSE)
fig <- fig %>%
    animation_button(x = 1, xanchor = "right", y = 0, yanchor = "bottom")
fig <- fig %>%
    animation_slider(currentvalue = list(prefix = "YEAR ", font = list(color = "red")))

fig

Plotly paketi kullanılarak hareketli görseller oluşturmak mümkündür.

4.3 Paketler İçinde Oluşturulabilecek Animasyonlar

Kullandığımız paketler içerisinde veri görselleştirme aşamasında yapılabilecek en iyi yöntemlerden biri de animasyon oluşturmaktır. Kullandığımız “ggplot2” paketini kullanarak bazı animasyonlar oluşturulmuştur. Farklı verilerden oluşan animasyonları göreceksiniz. Farklı veri tiplerine göre oluşturulabilecek animasyonlar gösterilmek istenmiştir. Plotly ve ggplot gibi paketler içerisinde ulaşabileceğiniz animasyon çeşitleri mevcuttur.

# ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, colour = country)) +
# geom_point(alpha = 0.7, show.legend = FALSE) + scale_colour_manual(values =
# country_colors) + scale_size(range = c(2, 12)) + scale_x_log10() +
# facet_wrap(~continent) + labs(title = 'Year: {frame_time}', x = 'GDP per
# capita', y = 'life expectancy') + transition_time(year) + ease_aes('linear')

# anim_save('271-ggplot2-animated-gif-chart-with-gganimate2.gif')

# a <- data.frame(group=c('A','B','C'), values=c(3,2,4), frame=rep('a',3)) b <-
# data.frame(group=c('A','B','C'), values=c(5,3,7), frame=rep('b',3)) data <-
# rbind(a,b)

# ggplot(a, aes(x=group, y=values, fill=group)) + geom_bar(stat='identity')


# ggplot(data, aes(x=group, y=values, fill=group)) + geom_bar(stat='identity')
# + theme_bw() +

# transition_states( frame, transition_length = 2, state_length = 1 ) +
# ease_aes('sine-in-out')

# anim_save('288-animated-barplot-transition.gif')

# p <- ggplot( gapminder, aes(x = gdpPercap, y=lifeExp, size = pop, colour =
# country) ) + geom_point(show.legend = FALSE, alpha = 0.7) +
# scale_color_viridis_d() + scale_size(range = c(2, 12)) + scale_x_log10() +
# labs(x = 'GDP per capita', y = 'Life expectancy')

# p + transition_time(year) + labs(title = 'Year: {frame_time}') +
# shadow_wake(wake_length = 0.1, alpha = FALSE)

# mean.temp <- airquality %>% group_by(Month) %>% summarise(Temp = mean(Temp))
# mean.temp

# a <- ggplot(mean.temp, aes(Month, Temp, fill = Temp)) + geom_col() +
# scale_fill_distiller(palette = 'Reds', direction = 1) + theme_minimal() +
# theme( panel.grid = element_blank(), panel.grid.major.y = element_line(color
# = 'white'), panel.ontop = TRUE )

# a + transition_states(Month, wrap = FALSE) + shadow_mark()


5. Büyük Veri Modelleme

5.1 Makine Öğrenmesi Nedir?

Matematiksel ve istatistiksel işlemler ile veriler üzerinden çıkarımlar yaparak tahminlerde bulunan sistemlerin bilgisayarlar ile modellenmesidir. Yapay zekanın, bir alt birim dalıdır. Veriler tam anlamıyla belge, ses, görüntü vb. gibi bilgiler anlamına gelir. Model ise makine öğreniminin son ürünüdür. Peki makine öğrenmesi süreci nelerden oluşuyor? Makine Öğrenimi, analitik modellerin yetersiz kaldığı durumlarda sorunları çözmek için oluşturulmuştur. Denklemler ve yasalar ümit vaat etmediğinde eğitim verilerini kullanarak bir model elde etmek için Makine Öğrenimi tekniklerinden yararlanırız.

5.2 Makine Öğrenmesi Nasıl Çalışır?

Makine öğrenimi algoritmaları, insan müdahalesi olmadan verilerden öğrenebilen ve deneyimler ile geliştirebilen programlardır. Makine öğrenimi algoritmaları denetimli öğrenme ve denetimsiz öğrenme olarak kategorize edilir.

5.2.1 Denetimli Öğrenme

Denetimli makine öğrenimi , belirsizlik dahilinde kanıta dayalı tahminler yapan bir model oluşturur. Denetimli bir öğrenme algoritması bilinen bir girdi verisi seti ve verilere bilinen yanıtları alır, ardından yeni verilere yanıt için makul tahminler oluşturmak üzere bir modeli eğitir. Tahmin etmeye çalıştığınız çıktı için bilinen verileriniz varsa denetimli öğrenmeyi kullanabilirsiniz.

Sınıflandırma Teknikleri

Örneğin bir e-postanın gerçek mi yoksa spam mı yoksa bir tümörün kanserli mi yoksa iyi huylu mu olduğu gibi, farklı yanıtlar öngörür. Sınıflandırma modelleri girdi verilerini kategorilere ayırır.

Verileriniz etiketlenebilir, kategorilere ayrılabilir veya belirli gruplara sınıflara ayrılabiliyorsa sınıflandır tekniğini kullanabilirsiniz. Örneğin, el yazısı tanıma uygulamaları harfleri ve sayıları tanımak için sınıflandırmayı kullanır. Sınıflandırma yapmak için yaygın algoritmalar, destek vektör makinesi(SVM) , karar ağaçları , k-en yakın komşu , Naive Bayes , diskriminant analizi, lojistik regresyon ve sinir ağlarını içerir.

Regresyon Teknikleri

Sürekli bir değeri tahmin etmek için kullanılır. Evin büyüklüğü, fiyatı vb. özellikleri göz önüne alındığında bir evin fiyatlarının tahmin edilmesi, regresyonun yaygın örneklerinden biridir. Bir veri aralığıyla çalışıyorsanız veya yanıtınızın niteliği sıcaklık veya bir ekipman parçasının arızalanmasına kadar geçen süre gibi gerçek bir sayı ise regresyon tekniklerini kullanabilrsiniz. Yaygın regresyon algoritmaları arasında doğrusal model , doğrusal olmayan model, regülasyon, kademeli regresyon , karar ağaçları , sinir ağları sayılabilir.

5.2.2 Denetimsiz Öğrenme

Denetimsiz (gözetimsiz) öğrenme, modeli denetlemenize gerek olmayan bir makine öğrenme tekniğidir. Bunun yerine, modelin bilgileri keşfetmek için kendi başına çalışmasına izin vermeniz gerekir. Denetimsiz öğrenme algoritmaları, denetimli öğrenmeye kıyasla daha karmaşık işleme görevleri gerçekleştirmenizi sağlar. Denetimsiz öğrenmede sistem öğretilmiyor, verilerden öğreniyor. Denetimsiz makine öğrenimi, verilerdeki bilinmeyen her türlü paterni bulur. Denetimsiz yöntemler, kategorizasyon için yararlı olabilecek özellikleri bulmanıza yardımcı olur.


6. Denetimli Makine Öğrenmesi

6.1 Train ve Test

Şekil 6.1: Train ve Test

Kullanacağımız modellerin tahmin performansını ölçmek için veriyi train ve test olarak ikiye bölmemiz gerekiyor. Bölüm 2.3’de belirttiğimiz yöntemlerden ilki (örneklem çekme) kullanıldı. Bu kadar büyük bir verinin hepsini modellere sokmaya çalışırsak hem sağlıklı sonuçlar alamayacağız, hem de kodların çalışması için çok uzun süre beklememiz gerekecek. Bu sebeple 500 gözlem içeren bir rastgele örneklem kullanıldı.

set.seed(101)
sample = sample.int(n = nrow(data_sample), size = floor(0.75 * nrow(data_sample)),
    replace = F)
train_sample = data_sample[sample, ]
test_sample = data_sample[-sample, ]

Çektiğimiz örneklemi %75’i train, %25’i test olacak şekilde rastgele ayırdık.

6.2 Destek Vektör Makineleri

Şekil 6.2: DVM

Destek Vektör Makineleri, temel olarak iki sınıfa ait verileri birbirinden en uygun şekilde ayırmak için kullanılır. Bunun için karar sınırları ya da diğer bir ifadeyle hiper düzlemler belirlenir. DVM’ler günümüzde yüz tanıma sistemlerinden, ses analizine kadar birçok sınıflandırma probleminde kullanılmaktadırlar.

Avantajları:

  • Yüksek boyutlu uzaylarda etkilidirler.
  • Boyut sayısının, örnemlem sayısından fazla olduğu durumlarda etkilidirler.
  • Karar fonksiyonunda bir takım eğitim noktaları kullanılır (“destek vektörler”). Dolayısıyla bellek verimli bir şekilde kullanılmış olur.
  • Çok yönlü: Karar fonksiyonu için çok farklı çekirdek fonksiyonları (“kernel functions”) kullanılabilmektedir.

R üzerinde nasıl çalıştığını görelim:

classifier1 = svm(formula = cardio ~ ., data = train_sample, scale = FALSE, type = "C-classification",
    kernel = "linear")

Train setimizle modeli kurduk.

summary(classifier1)

Call:
svm(formula = cardio ~ ., data = train_sample, type = "C-classification", 
    kernel = "linear", scale = FALSE)


Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  linear 
       cost:  1 

Number of Support Vectors:  256

 ( 127 129 )


Number of Classes:  2 

Levels: 
 Var Yok

Modeli özetlediğimizde kullanılan destek vektör sayısı ve bağımlı değişkeni görebiliyoruz.

y_pred = predict(classifier1, newdata = test_sample[-12])
cmlinear = table(test_sample[, 12], y_pred)
cmlinear
     y_pred
      Var Yok
  Var  39  25
  Yok  15  46

Train seti üzerinde kurduğumuz modelin, test seti üzerindeki tahminlerini görüyoruz.

accuracylinear = sum(diag(cmlinear))/dim(test_sample)[1]
accuracylinear
[1] 0.68

Son olarak bu tahminlerin doğruluk oranını hesapladık. %68 oranında bir doğruluk yakaladık.

6.3 Karar Ağaçları

Çok güçlü algoritmalar olan karar ağaçları kompleks ve büyük veri setlerinin çözümünde oldukça yararlanılan denetimli öğrenme algoritmaları ailesine aittir. Bunun yanında karar ağaçları rastgele orman (random forests) algoritmalarının temel bileşenleridir.

Şekil 6.3: Karar Ağaçları

Karar ağaçları ilk olarak recursive binary splitting ile başlar. Böylelikle regresyon için hata kareler ortalamasını, sınıflandırma için ise classification error rate, gini index veya deviance gibi prediction perfrormansına dayalı ölçekleri minimum yapacak en büyük ağaç (bushy tree) belirlenir. Regresyon modelinin yanıtı her gözlemin ait olduğu sınıfın ortalamsıdır. Bu yöntemin bir dezavantajı overfitting’dir. Yöntem training seti çok iyi öğrenir ancak test seti üzetindeki performansı düşüktür.

Karar ağaçlarında hedef değişken kategorik ise sınıflandırma algoritması, numerik değişken ise regresyon algoritması kullanılır. Veri setindeki hedef değişkenimiz kategorik olduğu için sınıflandırma algoritması kullanılacaktır.

Karar Ağaçlarının Avantajları:

  • Anlaması ve yorumlaması kolaydır. Kullanılan ağaç yapılar görselleştirilebilir.
  • Az oranda bir veri hazırlığına ihtiyaç duyar. Fakat unutulmamalıdır ki bu model kayıp değerleri desteklememektedir.
  • Kullanılan ağacın maliyeti, ağacı eğitmek için kullanılan veri noktalarının sayısıyla logaritmiktir.
  • Hem sayısal hem de kategorik verileri işleyebilir.
  • Çok çıktılı problemleri ele alabilmektedirler.
  • İstatistiksel testler kullanılarak bir modelin doğrulanması mümkündür.
  • Karar ağaçları, parametrik olmayan bir yöntem olarak düşünülebilir. Yani uzay dağılımı ve sınıflandırma yapısı hakkında bir yaklaşıma sahip değilledir.

R üzerinde nasıl çalıştığını görelim:

set.seed(101)
tree.model1 = tree(cardio ~ ., data = train_sample)

summary(tree.model1)

Classification tree:
tree(formula = cardio ~ ., data = train_sample)
Variables actually used in tree construction:
[1] "ap_hi"  "weight" "ap_lo"  "height" "active" "gluc"  
Number of terminal nodes:  10 
Residual mean deviance:  1.014 = 369.9 / 365 
Misclassification error rate: 0.2347 = 88 / 375 

Train seti ile modelimizi kurduk. Özet çıktısında ortalama sapma ve hata oranı gibi değerleri görebiliyoruz.

plot(tree.model1)
text(tree.model1, pretty = 0)

Grafiğini çizdirdiğimizde ise ağacın nasıl bir şekil aldığını görebiliyoruz.

Bu sefer train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz.

%62.4 doğruluk oranına sahibiz.

6.3.1 Budama

Budamada da aynı lasso regresyonda olduğu gibi bir penalization terimi mevcuttur. Amaç fonksiyonumuza \(\alpha|T|\) şeklinde bir kısıt vardır. Burada \(\alpha\) cost complexcity parametresi, \(|T|\) toplam node sayısını göstermektedir. Lasso’da olduğu gibi \(\alpha\) büyüdükçe modelde kullanılan node sayısı düşecek ancak modelin yanlılığıda artacaktır. Budamada optimal \(\alpha\) değerinin belirlenmesi için çapraz doğrulama (cross validation) kullanılır.

Şekil 6.3.1: Budama

set.seed(101)
tree.model2 = cv.tree(tree.model1, FUN = prune.misclass)
tree.model2
$size
[1] 10  9  8  6  5  2  1

$dev
[1] 111 111 121 113 112 112 182

$k
[1]      -Inf  0.000000  1.000000  2.000000  3.000000  3.666667 74.000000

$method
[1] "misclass"

attr(,"class")
[1] "prune"         "tree.sequence"
plot(tree.model2)

Optimal \(\alpha\) değerinin belirlenmesi için çizdirdiğimiz bu grafikte en yakın ve en düşük değeri almamız gerekiyor. Görüldüğü üzere, misclassification’ın en düşük değeri, size=2 olduğunda elde edilmiştir.

set.seed(12345)
tree.model2 = prune.misclass(tree.model1, best = 2)

Size=2 kullanarak modeli tekrar kurduk. Oluşan ağaca bakalım.

fit <- rpart(cardio ~ ., data = train_sample, method = "class")
rpart.plot(fit, extra = 106)

İlk grafik gibi karışık olmayan bir ağaç yapısıyla karşılaştık. Özet çıktılarını da alalım.

summary(tree.model2)

Classification tree:
snip.tree(tree = tree.model1, nodes = 3:2)
Variables actually used in tree construction:
[1] "ap_hi"
Number of terminal nodes:  2 
Residual mean deviance:  1.2 = 447.6 / 373 
Misclassification error rate: 0.2853 = 107 / 375 

Tahmin performansına bakıp bitirelim.

Görüldüğü gibi modelin test seti üzerindeki accuracy’si (doğruluk oranı) %66.4’dür. Doğru sınıflandırma yüzdesi artmıştır ve yorumlanması daha kolay bir ağacımız olmuştur.

6.4 Torbalama (Bagging)

Karar Ağaçları yüksek varyansa sahiptir. Bu problemi çözmek için Torbalama kullanılabilir. Torbalama iki temele dayanan son derece güçlü bir fikirdir:

  • Ortalama Alma: Varyansı azaltır.
  • Önyükleme (Bootstrapping): Bol miktarda eğitim veri seti.

bknz. Bagging (Torbalama) / Bootstrap Aggregating (Önyükleme Toplaması)

Şekil 6.4: Torbalama

Orjinal veri setinden elde edilen önyükleme örneklerine tahminciler uygulanarak bir topluluk oluşturulur. Burada önyükleme uygulaması, iadeli rastgele seçim yapıp alt örneklemler oluşturmak için kullanılır.

Oluşturulan alt örneklemler orjinal veri setindeki sayı ile aynı olacaktır. Bu nedenle bazı gözlemler önyükleme sonucunda oluşturulan örneklemlerde yer almazken bazıları iki veya daha fazla defa görülebilir. Tahminlerin birleştirilmesi aşamasında regresyon ağaçları için ortalama alınırken sınıflandırma ağaçlarında sonuçlar oylama ile belirlenir.

Torbalama, tutarsız bir tahminci değişkenin tahmin geçerliliğini de arttırabilir. Düşük yanlılık miktarına sahip ama yüksek varyanslı olan değişkenleri kullanarak onları daha elverişli hale getirir. Ayrıca deneysel sonuçlara göre torbalama yöntemi, tekil ağaçlara göre daha etkin sonuçlar vermektedir.

  • Orjinal veri kümesinden çoklu alt kümeler oluşturulur.
  • Bu alt grupların her birinde bir temel model (zayıf model) oluşturulmuştur.
  • Modeller paralel olarak çalışır ve birbirinden bağımsızdır.
  • Nihai tahminler, tüm modellerden gelen tahminler birleştirilerek belirlenir.

Modeli kuralım:

set.seed(101)
Bagging.model1 = randomForest(cardio ~ ., data = train_sample, mtry = 12, importance = TRUE)
Bagging.model1

Call:
 randomForest(formula = cardio ~ ., data = train_sample, mtry = 12,      importance = TRUE) 
               Type of random forest: classification
                     Number of trees: 500
No. of variables tried at each split: 12

        OOB estimate of  error rate: 33.87%
Confusion matrix:
    Var Yok class.error
Var 119  62   0.3425414
Yok  65 129   0.3350515
  • mtray: Değişken Sayısı (p)
  • Varsayılan örneklem sayısı 500.

Bagging modelimizi kurduk. Konfüzyon matris ve hata oranlarını görebiliyoruz.

varImpPlot(Bagging.model1, main = "Bagging Model")

Değişkenlerin doğruluk ve gini ölçütlerine göre önemlilik derecelerini bu grafik ile görebiliyoruz.

Büyük tansiyon (ap_hi) 2 grafikte de en önemli değişken olarak gözüküyor.

Modelin tahmin performansını inceleyelim.

Tekrardan train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz. %66.4 doğruluk oranına sahibiz.

Varsayılan olarak 500 örneklem kullanmıştık. Hata grafiğine bakıp bunu daha aza indirebilecek miyiz bakalım.

plot(Bagging.model1, main = "Bagging Model")

Eğer belli bir ağaç sayısından sonra çizgiler düzleşmeye başlasaydı o kısmı sınır olarak alıp iş yükümüzü hafifletebilirdik. Ancak bu grafiğe baktığımızda böyle bir şansımız olmadığını görüyoruz.

6.5 Rastgele Orman (Random Forest)

Çok etkili bir istatistiksel öğrenme yöntemidir. Bagging fikri üzerine kuruludur, ancak iyileştirme sağlar çünkü ağaçları korelasyonsuzlaştırır. Yine aynı şekilde bootstrap eğitim setleri üzerinde karar ağaçları inşaa edeceğiz fakat bu sefer farklı olarak, her bir ayrışımı yaparken p tane açıklayıcı değişkenin herbirini hesaba katmak yerine, bunlar içinden rasgele seçilen m tanesini kullanacağız. Böylelikle herbir bootstrap eğtim seti üzerinde çok çeşitli ağaçlar elde edilecek. Burada devreye ek bir parametre olarak seçilecek değişken sayısı girecek. Seçilecek değişken sayısı genel olarak \(\sqrt p\) şeklinde belirlenir. m=p durumunda ise random forest bagging’e dönüşür.

Şekil 6.5: Rastgele Orman

Neden bölünme için tüm p açıklayıcı değişken yerine rastgele bir m tanesini düşünüyoruz?

  • Varsayalım ki, diğer bazı orta derecede güçlü açıklayıcı değişkenler ile birlikte veri setinde çok güçlü bir açıklayıcı değişken var. O zaman bagging ağaçlarının çoğu veya hepsi ilk bölünme için çok güçlü açıklayıcı değişkeni kullanacak.
  • Bütün bagging ağaçları benzer görünecektir. Bu nedenle yapılan tüm tahminler yüksek oranda ilişkili olacaktır.
  • Yüksek korelasyonlu niceliklerin ortalamasının alınması varyansı pek fazla düşürmez. Random forests bagging ağaçlarını korelasyonsuzlaştırarak varyanstaki düşüşü arttırır.

Şimdi mtray değerini \(\sqrt p\) alarak randomforest yapalım.

set.seed(101)
Randomforest.model1 = randomForest(cardio ~ ., data = train_sample, mtry = 4, importance = TRUE)
Randomforest.model1

Call:
 randomForest(formula = cardio ~ ., data = train_sample, mtry = 4,      importance = TRUE) 
               Type of random forest: classification
                     Number of trees: 500
No. of variables tried at each split: 4

        OOB estimate of  error rate: 32.27%
Confusion matrix:
    Var Yok class.error
Var 122  59   0.3259669
Yok  62 132   0.3195876

Rastgele orman modelimizi kurduk. Konfüzyon matris ve hata oranlarını görebiliyoruz.

varImpPlot(Randomforest.model1, main = "Random Forest Model")

Tekrardan değişkenlerin önemlilik derecelerine bakıyoruz. ap_hi (büyük tansiyon) değişkeni yeniden en önemli değişken olarak gözüksede gini grafiğinde bmi (vücut kitle indeksi) en önemlisi olarak gözüküyor.

Modelin performansını inceleyelim.

Train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz.

%66.4 doğruluk oranına sahibiz. Bagging ile aynı sonucu aldık.

6.6 Yükseltme (Boosting)

Boosting’de bagging ve random forest gibi tahmin performansını arttırmaya yönelik bir yaklaşımdır. Onlardan farklı olarak boosting iterative bir yaklaşımdır ve her adımında bir önceki adımdaki performansı geliştirmeye çalışır.

Bagging ve random forest’ta her bir bootstrap training seti üzerine kurulabilecek en büyük ağaçlar kurulur ve böylece tahminlerin yanlılığı düşürülür. Ortalama alınarak tahminlerin varyansı indirgenmiş olunur. Boosting’de ise her adımda nispeten daha küçük bir ağaç kurulur ve o ağaçtan elde edilen bilgi bir sonraki adıma aktarılır. Böylece öğrenme yavaş yavaş gerçekleşir ve overfitting oluşmaz.

Şekil 6.6: Yükseltme

Yükseltme yöntemindeki temel fikir, veri setine farklı ağırlıklar verilmesi sonucu elde edilen ağaçlar topluluğundan çıkarsamalar yapılmasıdır. Başlangıçta tüm gözlemler eşit ağırlığa sahiptir. Ağaç topluluğu büyümeye başladıkça, problem bilgisine kurulu olarak ağırlıklandırmalar düzenlenir. Yanlış sınıflandırılan gözlemlerin ağırlığı arttırılırken, nadiren yanlış sınıflandırılan gözlemlerin ağırlığı azaltılır. Bu sayede ağaçlar zor durumlar karşısında kendini düzenleyebilme yeteneği kazanır.

Yükseltme yönteminin nasıl çalıştığını aşağıdaki adımlarla anlayalım:

  • Orjinal veri kümesinden bir alt küme oluşturulur.
  • Başlangıçta, tüm veri noktalarına eşit ağırlık verilir.
  • Bu alt kümede bir temel model oluşturulur.
  • Bu model, tüm veri kümesi için tahminler yapmak için kullanılır.

  • Hatalar gerçek değerler ve öngörülen değerler kullanılarak hesaplanır.
  • Yanlış öngörülen gözlemlere daha fazla ağırlık verilir. (Burada, sınıflandırılmamış olan üç tane mavi artı noktaya daha fazla ağırlık verilecektir.)

  • Başka bir model oluşturulur ve veri setinde tahminler yapılır. (Bu model önceki modeldeki hataları düzeltmeye çalışır.)
  • Benzer şekilde, her biri önceki modelin hatalarını düzelten çoklu modeller oluşturulur.
  • Son model (güçlü öğrenen), tüm modellerin ağırlıklı ortalamasıdır.

Boosting modelini oluşturalım:

train_sample$cardio = ifelse(train_sample$cardio == "Var", 1, 0)
train_sample$cardio = factor(train_sample$cardio)

test_sample$cardio = ifelse(test_sample$cardio == "Var", 1, 0)
test_sample$cardio = factor(test_sample$cardio)

Öncelikle bağımlı değişkenimizin (cardio) Var çıktısı 1, Yok çıktısını 0 olarak tekrardan atadık. Boosting modelin kurulması için gerekli.

set.seed(101)
boosting.model1 = gbm((unclass(cardio) - 1) ~ ., data = train_sample, distribution = "bernoulli",
    n.trees = 5000, interaction.depth = 3, verbose = F)
summary(boosting.model1)

                    var    rel.inf
bmi                 bmi 26.3231924
weight           weight 16.0032169
age                 age 14.5861669
height           height 14.1836009
ap_hi             ap_hi 10.3048401
ap_lo             ap_lo  6.7740393
cholesterol cholesterol  3.4637669
gluc               gluc  2.3314691
gender           gender  2.1389382
smoke             smoke  1.7647568
active           active  1.4590009
alco               alco  0.6670116

Modeli kurup özetini aldığımızda bagging ve random forest’ta gördüğümüz tarzda değişken önemliliğini gösteren bir grafikle karşılaşıyoruz.

Görüldüğü üzere bmi (vücut kitle indeksi) değişkeni en etkili değişken olarak gözüküyor.

Modelin performansına bakalım:

Train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz.

%64.8 doğruluk oranına sahibiz.

6.7 Lojistik Regresyon

Lojistik regresyon analizi, sınıflama ve atama işlemi yapmaya yardımcı olan bir regresyon yöntemidir. Bağımlı değişken üzerinde açıklayıcı değişkenlerin etkileri olasılık olarak elde edilerek risk faktörlerinin olasılık olarak belirlenmesi sağlanır. Lojistik regresyonun amacı, iki yönlü karakteristiği olan bağımlı değişkenle ilgili bir dizi bağımsız değişken arasında uygun ilişkiyi tanımlamak için en uygun modeli bulmaktır.

Lineer regresyonda bağımsız değişkenlerin parametreleri Ordinary Least Squares (OLS) yöntemiyle tahmin edilirken Lojistik regresyonda parametreler Maximum Likelihood (MLE) yöntemiyle hesaplanıyor. MLE yönteminin amacı sonsuz parametre havuzundan veri setinin görülme olasılığını maksimize eden en iyi parametreleri seçmek.

Şekil 6.7: Lojistik Regresyon

Lojistik regresyon, bir sonucu belirleyen bir veya daha fazla bağımsız değişken bulunan bir veri kümesini analiz etmek için kullanılan istatistiksel bir yöntemdir. Sonuç, ikili bir değişkenle ölçülür (yalnızca iki olası sonuç vardır).

Lojistik regresyonda, bağımlı değişken ikili veya ikili, yani yalnızca 1 (doğru, başarı, hamile vb.) Veya 0 (yanlış, hata, gebe olmayan vb.) Olarak kodlanmış verileri içeriyor.

Lojistik regresyonun amacı, iki yönlü karakteristiği (bağımlı değişken = yanıt veya sonuç değişkeni) ile ilgili bir dizi bağımsız (öngörücü veya açıklayıcı) değişken arasındaki ilişkiyi tanımlamak için en uygun (henüz biyolojik olarak makul) modeli bulmaktır.

Lojistik regresyon modelini kuralım:

lojistik.model <- glm(cardio ~ ., data = train_sample, family = binomial)
summary(lojistik.model)

Call:
glm(formula = cardio ~ ., family = binomial, data = train_sample)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-3.4084  -0.9295  -0.4810   0.9462   2.0428  

Coefficients:
                                  Estimate Std. Error z value Pr(>|z|)    
(Intercept)                     -1.105e+01  5.668e+00  -1.950   0.0512 .  
age                              2.432e-02  1.835e-02   1.325   0.1851    
genderKadin                     -2.233e-01  3.071e-01  -0.727   0.4672    
height                           2.819e-03  3.314e-02   0.085   0.9322    
weight                           2.518e-02  2.774e-02   0.908   0.3639    
ap_hi                            5.428e-02  9.033e-03   6.009 1.87e-09 ***
ap_lo                           -1.218e-04  1.226e-03  -0.099   0.9209    
cholesterolNormalin Cok Ustunde  8.470e-01  3.981e-01   2.128   0.0334 *  
cholesterolNormalin Ustunde     -6.869e-02  3.385e-01  -0.203   0.8392    
glucNormalin Cok Ustunde        -9.835e-01  4.823e-01  -2.039   0.0414 *  
glucNormalin Ustunde            -4.879e-01  4.749e-01  -1.027   0.3042    
smokeSigara icmeyen              4.717e-01  4.306e-01   1.095   0.2733    
alcoAlkol icmeyen                9.246e-01  5.691e-01   1.625   0.1042    
activeAktif Degil                5.308e-01  3.000e-01   1.769   0.0769 .  
bmi                             -2.573e-02  6.570e-02  -0.392   0.6953    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 519.41  on 374  degrees of freedom
Residual deviance: 428.31  on 360  degrees of freedom
AIC: 458.31

Number of Fisher Scoring iterations: 5

Regresyon modelimizi kurduk. Hata, z değerleri, AIC vb. çoğu değeri görebiliyoruz. Tahmin performansına bakalım.

Train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz.

%68 doğruluk oranına sahibiz.

6.7.1 Çoklu Bağlantı (Multicollinearity)

Regresyonda, “çoklu bağlantı”, diğer tahmin edicilerle ilişkili tahmin edicileri ifade eder. Çoklu bağlantı, modeliniz yalnızca yanıt değişkeninizle değil, aynı zamanda birbirleriyle de ilişkili olan birden çok faktör içerdiğinde ortaya çıkar. Başka bir deyişle, biraz fazla olan faktörleriniz olduğunda ortaya çıkar.

Eğer modelimizde çoklu bağlantı problemi var ise bunu düzeltip tekrar bakmamız gerekiyor. Bu problemin varlığını kontrol etmek için en kolay yöntem vif kodunu kullanmaktır.

vif(lojistik.model)
                GVIF Df GVIF^(1/(2*Df))
age         1.071497  1        1.035132
gender      1.613481  1        1.270229
height      5.240991  1        2.289321
weight      9.557930  1        3.091590
ap_hi       1.204384  1        1.097444
ap_lo       1.098764  1        1.048220
cholesterol 1.237484  2        1.054715
gluc        1.305899  2        1.068999
smoke       1.380185  1        1.174813
alco        1.214596  1        1.102087
active      1.039142  1        1.019383
bmi         9.109234  1        3.018151

Vif değeri 10’dan büyük değerler olduğu zaman çoklu bağlantı probleminden söz edebiliyoruz. Baktığımızda 10’dan büyük bir değerle karşılaşmıyoruz. Çoklu bağlantı problemimiz yok.

6.8 En İyi Model

MODEL DOĞRULUK ORANI
Destek Vektör Makineleri %68
Karar Ağaçları %62.4
Budama (Pruning) %66.4
Torbalama (Bagging) %66.4
Rastgele Orman %66.4
Yükseltme (Boosting) %64.8
Lojistik Regresyon %68

Tablodan her yöntem için accuracy (doğruluk) oranı değerlerine baktığımızda DVM ve Lojistik Regresyon yöntemlerinin bu veri için en iyi çalışan yöntemler olduğunu söyleyebiliriz.


7. Denetimsiz Makine Öğrenmesi

Denetimsiz makine öğrenme tekniklerinin bazı uygulamaları şunlardır:

  • Kümeleme, veri kümesini benzerliklerine göre otomatik olarak gruplara ayırır.

  • Anomali tespiti, veri kümenizdeki olağandışı veri noktalarını keşfedebilir. Hileli işlemler bulmak için yararlıdır.

  • İlişkilendirme madenciliği, veri kümenizde genellikle birlikte ortaya çıkan öğe kümelerini tanımlar.

  • Gizli değişken modeller, veri ön işleme için yaygın olarak kullanılmaktadır. Veri kümesindeki özellik sayısını azaltmak veya veri kümesini birden çok bileşene ayırmak gibi problemlerde kullanılabilir.

Denetimli ve denetimsiz makine öğrenimi arasında seçim yapma konusunda karar vermek istiyorsanız:

  • Bir tahmin yapmak için bir (örneğin, sıcaklık veya hisse senedi fiyatı veya bir sınıflandırma gibi sürekli bir değişkenin gelecekteki değeri), örneğin, web kamerası video çekimlerindeki araba markalarını tanımlamak için bir model eğitmeniz gerekiyorsa denetimli öğrenmeyi seçin.

  • Verilerinizi keşfetmeniz gerekiyorsa ve verileri kümelere ayırmak gibi iyi bir dahili temsil bulmak için bir model eğitmek istiyorsanız, denetimsiz öğrenmeyi seçin.

7.1 Kümeleme Nedir?

Şekil 7.1: Kümeleme

Denetimsiz öğrenme söz konusu olduğunda kümelenme önemli bir kavramdır. Genel olarak, kategorize edilmemiş verilerden oluşan bir koleksiyonda bir yapı veya model bulma ile ilgilenir. Kümeleme algoritmaları verilerinizi işler ve verilerde varsa doğal kümeleri (grupları) bulur. Ayrıca algoritmalarınızın kaç kümeyi tanımlaması gerektiğini de değiştirebilirsiniz. Bu grupların ayrıntı düzeyini ayarlamanıza olanak tanır.

7.2 K-Means Kümeleme

K, her yineleme için en yüksek değeri bulmanıza yardımcı olan yinelemeli bir kümeleme algoritması anlamına gelir. Başlangıçta, istenilen sayıda küme seçilir. Bu kümeleme yönteminde, veri noktalarını k gruplarına kümelemeniz gerekir. Daha büyük bir k, aynı şekilde daha fazla ayrıntıya sahip daha küçük gruplar anlamına gelir.

Şekil 7.2: K-Means Kümeleme

Şimdi R üzerinde bu analizin nasıl yapıldığını göreceğiz. Ancak analize geçmeden önce daha önceden büyük verimizden çektiğimiz 500 gözlemlik örneklemi daha da küçültüp (50 gözleme indirip) sağlıklı bir görsel oluşturacağız.

set.seed(103)
data_sample2 = data_sample[sample(nrow(data_sample), 50), ]

df = data_sample2 %>%
    select(age, height, weight, ap_hi, ap_lo, bmi) %>%
    scale()
head(df)
             age     height      weight      ap_hi      ap_lo        bmi
69081 -0.5352747  0.6332190 -1.69631233 -1.2231343 -1.0253132 -1.8907022
48683 -0.3994182 -0.1517632  0.05762952  1.4709941  0.7273589  0.1236830
24104 -1.2145573 -0.6750848 -0.75670063 -0.3250915 -0.1489771 -0.5117913
51237 -1.7579834  1.1565406  2.25005683 -0.3250915 -0.1489771  1.5877724
6743   0.6874340 -1.3292367 -0.06765204 -0.7741129 -0.1489771  0.5569583
1329   0.6874340  1.1565406  1.99949371  4.1651224  3.3563671  1.3587831

50 gözlem içeren yeni bir örneklem oluşturduk. Select komutu ile sadece nümerik değişkenleri (k-means kümeleme yöntemi nümerik değişkenlerle çalıştığı için) seçtik. Scale komutu ile de ölçeklendirme yaptık. Şimdi kümelemeye hazırız.

k2 = kmeans(df, centers = 2, nstart = 25)
str(k2)
List of 9
 $ cluster     : Named int [1:50] 1 2 1 2 1 2 1 1 1 2 ...
  ..- attr(*, "names")= chr [1:50] "69081" "48683" "24104" "51237" ...
 $ centers     : num [1:2, 1:6] -0.173 0.445 -0.13 0.334 -0.466 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:2] "1" "2"
  .. ..$ : chr [1:6] "age" "height" "weight" "ap_hi" ...
 $ totss       : num 294
 $ withinss    : num [1:2] 109.8 93.1
 $ tot.withinss: num 203
 $ betweenss   : num 91.1
 $ size        : int [1:2] 36 14
 $ iter        : int 1
 $ ifault      : int 0
 - attr(*, "class")= chr "kmeans"
  • nstart: Çoklu başlangıç noktası atamak için kullanılıyor.

  • centers: k tane merkez noktası oluşturmak için kullanılıyor.

Öncelikle kendi belirdiğimiz k ile analizimizi yaptık. Rastgele olarak k=2 seçtim ve veriyi ikiye ayırmış olduk. Hangi gözlemin hangi kümede olduğu, kümelerin gözlem sayısı gibi özellikleri görebiliyoruz.

fviz_cluster(k2, data = df)

Burada ise grafik üzerinde kümelemenin nasıl yapıldığını görüyoruz. Şimdi eğer k değerini farklı verseydik ne olacağını görelim.

k3 <- kmeans(df, centers = 3, nstart = 25)
k4 <- kmeans(df, centers = 4, nstart = 25)
k5 <- kmeans(df, centers = 5, nstart = 25)

p1 <- fviz_cluster(k2, geom = "point", data = df) + ggtitle("k=2")
p2 <- fviz_cluster(k3, geom = "point", data = df) + ggtitle("k=3")
p3 <- fviz_cluster(k4, geom = "point", data = df) + ggtitle("k=4")
p4 <- fviz_cluster(k5, geom = "point", data = df) + ggtitle("k=5")

grid.arrange(p1, p2, p3, p4, nrow = 2)

k=2,3,4 ve 5 değerleri için kümelerin nasıl ayrıldığını görüyoruz. En iyi k değerlerini bulmak için kullanılan bazı yöntemler var. Şimdi onlara bakalım.

7.2.1 Elbow Yöntemi

  • Kümeler için hata hesaplama.
set.seed(134)
fviz_nbclust(df, kmeans, method = "wss")

Genel olarak en büyük düşüşün yaşandığı k seçilir. Burada 2 ve 3 değerleri uygun gibi duruyor. Sonraki yöntemimize bakıp karar verelim.

7.2.2 Average Silhoutte Yöntemi

  • Küme içi kalite skoru hesaplama.
fviz_nbclust(df, kmeans, method = "silhouette")

Burada da görüldüğün üzere k=2 seçmek en mantıklı seçim olacaktır.

set.seed(123)
final <- kmeans(df, 2, nstart = 24)
print(final)
K-means clustering with 2 clusters of sizes 14, 36

Cluster means:
         age     height    weight      ap_hi      ap_lo        bmi
1  0.4448331  0.3341782  1.198587  0.9642413  0.9151452  1.0817642
2 -0.1729906 -0.1299582 -0.466117 -0.3749827 -0.3558898 -0.4206861

Clustering vector:
69081 48683 24104 51237  6743  1329 25681 60633  3691 42341 20280 38152 14493 
    2     1     2     1     2     1     2     2     2     1     2     1     2 
10694   863  7878 67307 59125  4019 39966 42111 58406 14026 15301 68745 52742 
    2     2     2     2     1     2     2     2     2     2     2     1     2 
 5825 58142  9526 34384    25 54498  6172 58509 31154 61361 65010 45759 67787 
    2     2     2     2     2     2     2     1     2     1     2     2     2 
30101 46233 20657 27890  8617 14750 46684 28538 45432 19570 51795 
    1     1     2     2     1     2     1     1     2     2     2 

Within cluster sum of squares by cluster:
[1]  93.0985 109.8310
 (between_SS / total_SS =  31.0 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"      

Örneklemimizi ikiye ayırmış olduk. İlk küme 14, ikinci küme 36 gözlem içeriyor. Kümelerin değişken ortalamalarını, hangi gözlemin hangi kümede olduğunu ve kümelerin kareler toplamını görüyoruz.

7.3 Hiyerarşik Kümeleme

Veri noktalarınızı üst ve alt kümeler halinde kümeler. Müşterilerinizi daha genç ve daha büyük yaşlara bölebilir ve ardından bu grupların her birini kendi bireysel kümelerine de bölebilirsiniz.

Şekil 7.3: Hiyerarşik Kümeleme

Hiyerarşik kümeleme de K-Ortalamalar tekniği gibi aslında aynı sonucu hedefliyor fakat, farklı bir yöntemle, taneciklerden bütüne doğru ilerliyor. K-Ortalamalar tekniğinde olduğu gibi küme kullanıcıdan sayısını istemiyor. Uygulamaya geçelim.

Bu yöntemi uygulamak için 4 farklı tekniğimiz var. Bunlara linkage (bağlantı) metotları deniyor.

  • Average: Kümeler arası aritmetik ortalamayı kontrol eder.

  • Single: En yakın komşu ile benzerliği kontrol eder.

  • Complete: En uzak komşu ile benzerliği kontrol eder.

  • Ward: Kümeler arası kareler toplamını kontrol eder.

En iyi metotu bulmak için aşağıdaki fonksiyonu kullanacağız.

m <- c("average", "single", "complete", "ward")
names(m) <- c("average", "single", "complete", "ward")
ac <- function(x) {
    agnes(dist(df, method = "euclidean"), method = x)$ac
}
map_dbl(m, ac)
  average    single  complete      ward 
0.7676608 0.6420281 0.8557998 0.8985124 

Görüldüğü üzere “ward” en iyi çalışan metotdur.

hc <- hclust(dist(df, method = "euclidean"), method = "ward.D2")
hc

Call:
hclust(d = dist(df, method = "euclidean"), method = "ward.D2")

Cluster method   : ward.D2 
Distance         : euclidean 
Number of objects: 50 
plot(hc, cex = 0.7)

Ward yöntemini kullanarak analizi yaptık ve dendogramı çizdirdik. Bu ağacı nereden keseceğimize karar vereceğiz.

K-Means’de kullandığımız Elbow ve Average Silhoutte yöntemleri burada da kullanılıyor.

7.3.1 Elbow Yöntemi

  • Kümeler için hata hesaplama.
fviz_nbclust(df, FUN = hcut, method = "wss")

Burada ki fark “FUN=hcut” belirlenip, hiyerarşik için bu yöntemi kullandık. 2 ya da 3 uygun gözüküyor.

7.2.2 Average Silhoutte Yöntemi

  • Küme içi kalite skoru hesaplama.
fviz_nbclust(df, FUN = hcut, method = "silhouette")

Burada da tekrardan 2 sonucunu elde ettik. Ancak bu sefer k=3 alarak devam etmek istiyorum. Elbow da bunu destekliyor.

sub_grp <- cutree(hc, k = 3)
table(sub_grp)
sub_grp
 1  2  3 
14 24 12 

14 gözlem ilk kümeye, 24 gözlem ikinci kümeye ve 12 gözlem üçüncü kümeye ayrıldı.

fviz_cluster(list(data = df, cluster = sub_grp))

Kümelerin grafiği yukarıda ki gibidir. Son olarak dendogram üzerinden gösterip bitirelim.

plot(hc, cex = 0.6)
rect.hclust(hc, k = 3, border = 2:5)

Dendogram üzerinde bütün gözlemlerin hangi kümede olduğunu görebiliyoruz.


8. Özet

8.1 İşlenen Konular

8.1.1 Veriyi Keşfetmek

  1. Veriyi Düzenleme
  • Örneklem çekme, değişken oluşturma, yeniden şekillendirme ve özetleme
  • data.table
  • dplyr
  • sparklyr
  1. Veriyi Görselleştirme
  • ggplot2
  • cowplot
  • ggExtra
  • plotly
  • gganimate

8.1.2 Veriyi Modelleme

  1. Karar Ağaçları
  • Sınıflandırma
  • rpart
  • rpart.plot
  1. Rastgele Ormanlar
  • Sınıflandırma
  • RandomForest
  1. Model Oluşturma ve Değerlendirme
  • modelr
  • caret
  1. Destek Vektör Makineleri
  • Destek vektör sınıflandırıcıları
  • Lojistik regresyon
  • Modellerin ayarlanması ve değerlendirilmesi
  • e1071

Kaynaklar